UNIX下有5中I/O模型,分别是阻塞式、非阻塞式、IO复用、信号驱动式、异步IO。
阻塞式IO
一般最常用的是这种阻塞式IO,顾名思义,所有套接字都是阻塞的,比如读数据,如果没有数据可读,就会一直阻塞在这里。
非阻塞式IO
前三次调用recvfrom读数据时,没有数据可以读,内核会直接返回一个错误,而不是让进程阻塞在这。
IO多路复用模型
我们可以调用select或者poll函数,这样进程不会阻塞在真正的IO上,而是、一直在等待何时可以进行IO。
这种方式跟非阻塞式相比,有点相像。非阻塞式中是一直循环调用读函数,等待真正可以读数据的时机发生。
IO复用中是不是对循环读取的过程做了一个封装?
这种方式跟阻塞式相比,好像并没有什么优势,但当进程打开多个文件描述符时,这种模型的优势就显现出来了。
信号驱动式IO
这种呢方式是利用系统的信号机制,先定义处理SIGIO的程序,等数据准备好之后,系统发送SIGIO信号通知进程。
采用这种模型,在等待数据期间不用阻塞,进程可以先做着其他事情,等信号来了再开始进行IO。
异步IO模型
应用进程调用aio_read,然后内核就会去等待数据,数据包准备好之后就读取(将数据从内核空间复制到用户空间),等读取完成后再通知进程。
在内核执行IO期间,进程不会被阻塞。
各种模型对比
对比这几种模型,阻塞式IO就像你亲自去办一件事情,由于你去早了,所以需要等待一段时间。
非阻塞式IO是你每隔一会就打电话问一下,最后可以了,你就去把事情办了。
IO复用是,你打电话告诉对方,等可以了就通知你。这期间你先不挂断电话,要一直等着。然后过一段时间对方通知你可以了,你再去完成这件事。
信号驱动式,你打电话告诉对方,等时机成熟之后通知你,然后你就挂断电话去做其他事情了,等对方来电话通知你,你再去做这件事。
异步IO是,你把你想做的事打电话告诉别人,然后他就去做了,等他做完之后再通知你。
其中,前四种都是同步IO模型,其中的IO操作都会阻塞进程。
参考
- 《UNIX网络编程(卷一第三版)》
欢迎与我分享你的看法。
转载请注明出处:http://taowusheng.cn/